package com.blog.service;

import com.blog.dao.BlogDAO;
import com.blog.dao.TypeDAO;
import com.blog.dao.UserDAO;

import com.blog.domain.Blog;
import com.blog.domain.Type;
import com.blog.domain.User;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Blog entities
 * 
 */

@Service("BlogService")
@Transactional
public class BlogServiceImpl implements BlogService {

	/**
	 * DAO injected by Spring that manages Blog entities
	 * 
	 */
	@Autowired
	private BlogDAO blogDAO;

	/**
	 * DAO injected by Spring that manages Type entities
	 * 
	 */
	@Autowired
	private TypeDAO typeDAO;

	/**
	 * DAO injected by Spring that manages User entities
	 * 
	 */
	@Autowired
	private UserDAO userDAO;

	/**
	 * Instantiates a new BlogServiceImpl.
	 *
	 */
	public BlogServiceImpl() {
	}

	/**
	 * Save an existing Blog entity
	 * 
	 */
	@Transactional
	public void saveBlog(Blog blog) {
		Blog existingBlog = blogDAO.findBlogByPrimaryKey(blog.getId());

		if (existingBlog != null) {
			if (existingBlog != blog) {
				existingBlog.setId(blog.getId());
				existingBlog.setTitle(blog.getTitle());
				existingBlog.setContent(blog.getContent());
				existingBlog.setDate(blog.getDate());
				existingBlog.setReader(blog.getReader());
			}
			blog = blogDAO.store(existingBlog);
		} else {
			blog = blogDAO.store(blog);
		}
		blogDAO.flush();
	}

	/**
	 * Return all Blog entity
	 * 
	 */
	@Transactional
	public List<Blog> findAllBlogs(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Blog>(blogDAO.findAllBlogs(startResult, maxRows));
	}

	/**
	 */
	@Transactional
	public Blog findBlogByPrimaryKey(Integer id) {
		return blogDAO.findBlogByPrimaryKey(id);
	}

	/**
	 * Return a count of all Blog entity
	 * 
	 */
	@Transactional
	public Integer countBlogs() {
		return ((Long) blogDAO.createQuerySingleResult("select count(o) from Blog o").getSingleResult()).intValue();
	}

	/**
	 * Save an existing User entity
	 * 
	 */
	@Transactional
	public Blog saveBlogUser(Integer id, User related_user) {
		Blog blog = blogDAO.findBlogByPrimaryKey(id, -1, -1);
		User existinguser = userDAO.findUserByPrimaryKey(related_user.getId());

		// copy into the existing record to preserve existing relationships
		if (existinguser != null) {
			existinguser.setId(related_user.getId());
			existinguser.setUsername(related_user.getUsername());
			existinguser.setPassword(related_user.getPassword());
			existinguser.setNickName(related_user.getNickName());
			existinguser.setSex(related_user.getSex());
			existinguser.setRegister(related_user.getRegister());
			existinguser.setImage(related_user.getImage());
			related_user = existinguser;
		} else {
			related_user = userDAO.store(related_user);
			userDAO.flush();
		}

		blog.setUser(related_user);
		related_user.getBlogs().add(blog);
		blog = blogDAO.store(blog);
		blogDAO.flush();

		related_user = userDAO.store(related_user);
		userDAO.flush();

		return blog;
	}

	/**
	 * Delete an existing Type entity
	 * 
	 */
	@Transactional
	public Blog deleteBlogType(Integer blog_id, Integer related_type_id) {
		Blog blog = blogDAO.findBlogByPrimaryKey(blog_id, -1, -1);
		Type related_type = typeDAO.findTypeByPrimaryKey(related_type_id, -1, -1);

		blog.setType(null);
		related_type.getBlogs().remove(blog);
		blog = blogDAO.store(blog);
		blogDAO.flush();

		related_type = typeDAO.store(related_type);
		typeDAO.flush();

		typeDAO.remove(related_type);
		typeDAO.flush();

		return blog;
	}

	/**
	 * Load an existing Blog entity
	 * 
	 */
	@Transactional
	public Set<Blog> loadBlogs() {
		return blogDAO.findAllBlogs();
	}

	/**
	 * Save an existing Type entity
	 * 
	 */
	@Transactional
	public Blog saveBlogType(Integer id, Type related_type) {
		Blog blog = blogDAO.findBlogByPrimaryKey(id, -1, -1);
		Type existingtype = typeDAO.findTypeByPrimaryKey(related_type.getId());

		// copy into the existing record to preserve existing relationships
		if (existingtype != null) {
			existingtype.setId(related_type.getId());
			existingtype.setName(related_type.getName());
			related_type = existingtype;
		} else {
			related_type = typeDAO.store(related_type);
			typeDAO.flush();
		}

		blog.setType(related_type);
		related_type.getBlogs().add(blog);
		blog = blogDAO.store(blog);
		blogDAO.flush();

		related_type = typeDAO.store(related_type);
		typeDAO.flush();

		return blog;
	}

	/**
	 * Delete an existing Blog entity
	 * 
	 */
	@Transactional
	public void deleteBlog(Blog blog) {
		blogDAO.remove(blog);
		blogDAO.flush();
	}

	/**
	 * Delete an existing User entity
	 * 
	 */
	@Transactional
	public Blog deleteBlogUser(Integer blog_id, Integer related_user_id) {
		Blog blog = blogDAO.findBlogByPrimaryKey(blog_id, -1, -1);
		User related_user = userDAO.findUserByPrimaryKey(related_user_id, -1, -1);

		blog.setUser(null);
		related_user.getBlogs().remove(blog);
		blog = blogDAO.store(blog);
		blogDAO.flush();

		related_user = userDAO.store(related_user);
		userDAO.flush();

		userDAO.remove(related_user);
		userDAO.flush();

		return blog;
	}

}
